home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archivers / SignArch / SignArch.rexx < prev    next >
OS/2 REXX Batch file  |  1996-09-26  |  36KB  |  1,292 lines

  1. /* SignArch v1.1, should be viewed with a tabsize of four */
  2.  
  3. /*
  4.     SignArch, message digests a list of files, and archives everything
  5.     Copyright (C) 1994 Jens T. Berger Thielemann
  6.  
  7.     This program is free software; you can redistribute it and/or modify it
  8.     under  the  terms of the GNU General Public License as published by the
  9.     Free  Software Foundation; either version 2 of the License, or (at your
  10.     option) any later version.
  11.  
  12.     This  program  is  distributed  in the hope that it will be useful, but
  13.     WITHOUT   ANY   WARRANTY;   without   even   the  implied  warranty  of
  14.     MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE.  See the GNU
  15.     General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License along
  18.     with this program; if not, write to the Free Software Foundation, Inc.,
  19.     675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.     To contact the author:
  22.  
  23.     <jensthi@ifi.uio.no>
  24.  
  25.     or
  26.  
  27.     Jens Berger
  28.     Spektrumveien 4
  29.     N-0666 Oslo
  30.     Norway
  31.  
  32.     or
  33.  
  34.     Send   a   message   in   POST   to   J.   BERGER  on  Trashcan  (A)BBS
  35.     [(+47) 22 25 74 78 or (+47) 22 25 88 22].
  36.  
  37.  
  38. $VER: SignArch 1.1 (16.12.94) Copyright © 1994 Jens T. Berger Thielemann
  39.  
  40. */
  41.  
  42. Signal On Break_c
  43. Signal On Break_d
  44.  
  45. Say "SignArch v1.1 (C) 1994-95 Jens T. Berger Thielemann, <jensthi@ifi.uio.no>"
  46.  
  47. _waitforreturn = 0
  48.  
  49. Address Command "ChkDate"
  50. DateIsValid = rc
  51. If DateIsValid ~= 0 Then Do Until DateIsValid = 0
  52.     Say ""
  53.     Address Command "Date"
  54.     Say ""
  55.     Say "THE DATE ABOVE IS NOT CORRECT. Thus, a false time-issue would"
  56.     Say "have been created.  Please enter correct date below, syntax"
  57.     Say "DD-MMM-YY."
  58.     Address Command "Date ?"
  59.     Address Command "ChkDate"
  60.     DateIsValid = rc
  61. End
  62.  
  63. /*
  64. *
  65. * Check that we're running under at least 2.0
  66. *
  67. */
  68.  
  69.  
  70. Time('R')
  71.  
  72. Options Failat 21
  73. Options Results
  74. Address Command "Version >nil: exec.library 37"
  75. If rc > 0 Then Do
  76.     Say "***ERROR: Needs Kick 2.0!"
  77.     Exit
  78. End
  79.  
  80. /*
  81. *
  82. * Our task pointer is unique, if it can't be obtained, we will
  83. * get write access on the file below, and thus ensure that nobody
  84. * else is able to open the file simultaneously, and thus that
  85. * conflict with temporary files is avoided.
  86. *
  87. */
  88.  
  89.  
  90. AddLib('rexxsupport.library',0,-30,0)
  91.  
  92. If Show("Libraries","rexxsupport.library") Then Do
  93.     Address
  94.     ExecBase = import("0000 0004"X, 4)
  95.     ThisTask = c2x(import(offset(execbase,276),4))
  96.     UniqueID = ThisTask
  97.     Address
  98.     UniqueID = Strip(UniqueID)
  99. End
  100. Else Do
  101.     If Open('saisrunning', "T:SignArch is running!", 'W') = 0 Then Do
  102.         Say "***ERROR: Another copy of SignArch is already running!"
  103.         Call Quit
  104.     End
  105.     Else UniqueID = ""
  106. End
  107.  
  108. pgpcommand = "PGP"
  109. md5command = "MD5Sum"
  110. lhacommand = "LhA"
  111.  
  112. /* Trace ?ACEILRS */
  113.  
  114. If Open('pgpenv', "ENV:SignArchGUIPaths", 'R') Then Do
  115.     Do While Eof('pgpenv') = 0
  116.         tmpline = ReadLn('pgpenv')
  117.         If Left(Upper(tmpline), 4) = "PGP:" Then pgpcommand = Right(tmpline, Length(tmpline)-4)
  118.         If Left(Upper(tmpline), 4) = "LHA:" Then lhacommand = Right(tmpline, Length(tmpline)-4)
  119.         If Left(Upper(tmpline), 4) = "MD5:" Then md5command = Right(tmpline, Length(tmpline)-4)
  120.         If Left(Upper(tmpline), 4) = "SMI:" Then Do
  121.             If Strip(Upper(Right(tmpline, Length(tmpline)-4))) = "TRUE" Then sumfileicon = 1
  122.         End
  123.     End
  124.     Close('pgpenv')
  125. End
  126.  
  127.  
  128. /*
  129. *
  130. * Get the name of the CommandFile
  131. *
  132. */
  133.  
  134. Parse Arg FILELIST
  135.  
  136. filelist = Strip(filelist)
  137.  
  138. /* Show some info & ask for name of CommandFile if requested */
  139.  
  140. If filelist = "" | filelist = "?" Then Do
  141.     Say ""
  142.     Say "Message digests a list of files, and archives everything.  Useful to avoid"
  143.     Say "tampering of distributed files."
  144.     Say ""
  145.     Say "SignArch comes with ABSOLUTELY NO WARRANTY; details on this and"
  146.     Say "distribution conditions in the GNU General Public License file."
  147.     Say "To contact the author, write to:"
  148.     Say "Jens Berger, Spektrumvn. 4, N-0666 Oslo, Norway."
  149.     Say "or send  a  message  in  POST  to  J.   BERGER  on  Trashcan  (A)BBS"
  150.     Say "[(+47) 22 25 74 78 or (+47) 22 25 88 22]."
  151.     Say ""
  152.     AddLib("rexxreqtools.library", 0, -30, 0)
  153.  
  154.     /* Use reqtools if possible */
  155.  
  156.     If Show("Libraries","rexxreqtools.library") Then Do
  157.         filelist = rtfilerequest( , , "Select filelist", , "rtfi_flags = freqf_patgad" , )
  158.         If rtresult = 0 Then Do
  159.             Say "***ERROR: No filelist picked!"
  160.             Call Quit
  161.         End
  162.     End
  163.     Else Do
  164.         Options Prompt "FILELIST/A: "
  165.         Pull filelist
  166.         filelist = Strip(filelist)
  167.     End
  168.     If filelist = "" Then Call Quit
  169. End
  170.  
  171. /*
  172. *
  173. * Various variables are initialized here
  174. *
  175. */
  176.  
  177. Address Command "Delete >nil: T:"||UniqueID||"SaKeyFile"
  178. Address Command "Delete >nil: T:"||UniqueID||"SaSigFile"
  179. Address Command "Delete >nil: T:"||UniqueID||"SaTmpFile"
  180. Address Command "Delete >nil: T:"||UniqueID||"SaListFile"
  181. Address Command "Delete >nil: T:"||UniqueID||"SaWTmpFile"
  182. Address Command "Delete >nil: T:"||UniqueID||"SaWildFile"
  183.  
  184.  
  185. /* Get the name of the current directory */
  186.  
  187. Address Command "Cd >T:"||UniqueID||"SACDFile"
  188. If Open('curdir', "T:"||UniqueID||"SaCDFile", 'R') = 1 Then Do
  189.     CurDir = Readln('curdir')
  190.     Pragma("Directory", CurDir)
  191.     Close('curdir')
  192. End
  193.  
  194.  
  195.  
  196. Say ""
  197.  
  198. ret = Open('flfile', FILELIST, 'R')
  199.  
  200. If ret = 0 Then Do
  201.     Say "***ERROR: Unable to open FileList file!"
  202.     Call Quit
  203. End
  204.  
  205. If Strip(ReadLn('flfile')) ~= "!!FILELIST!!" Then Do
  206.     Say "***ERROR: This file is not a filelist file, as the first line is not `!!FILELIST!!'"
  207.     Call Quit
  208. End
  209.  
  210. binchar = ""
  211. ascchar = ""
  212.  
  213. id = ""
  214. bannum = 0
  215. commnum = 0
  216.  
  217. sumicon = 0
  218. endwait = 0
  219. cryptfile = 0
  220. dontaddkey = 0
  221.  
  222. waittype = ""
  223. rootdir = ""
  224. deepchk = ""
  225. inctext = ""
  226.  
  227. arcwipe = "w"
  228.  
  229. addarmor = ""
  230.  
  231. fileforced = 0
  232.  
  233. wildcards = 1
  234.  
  235. sumonly = 0
  236.  
  237. /*
  238. *
  239. * Read the CommandFile line by line, and parse the commands/options
  240. *
  241. */
  242.  
  243.  
  244.  
  245. Say "Parsing options..."
  246.  
  247. lineread = ReadLn('flfile')
  248. Do While (Left(lineread, 3) = "***" | Left(lineread, 1) = ";" | lineread = "") & Eof('flfile') = 0 & fileforced = 0
  249.     Parse Var lineread type dummy
  250.     If Left(lineread, 3) = "***" & lineread ~= "" Then Do
  251.         If Length(lineread) > 11 Then Do
  252.             data = Right(lineread, Length(lineread)-11)
  253.             data = Strip(data)
  254.             data = Strip(data, 'B', '"')
  255.             data = '"'||data||'"'
  256.         End
  257.         Else data = ""
  258.  
  259.         type = Upper(Strip(type))
  260.         Select
  261.             When type = "***ADDARMOR" Then Do
  262.                 addarmor = "a"
  263.                 Say "Option enabled  : Final file will be ASCII-fied"
  264.             End
  265.  
  266.             When type = "***ADDCOMM" Then Do
  267.                 If data ~= "" Then Do
  268.                     command.commnum = Strip(Right(lineread, Length(lineread)-11))
  269.                     Say "Command added   : "command.commnum
  270.                     commnum = commnum+1
  271.                 End
  272.                 Else Do
  273.                     Say "***ERROR: No parameter for ADDCOMM option!"
  274.                     Call Quit
  275.                 End
  276.             End
  277.  
  278.             When type = "***ARCHIVE" Then Do
  279.                 ARCHIVE = data
  280.                 Say "Archive         : "||ARCHIVE
  281.             End
  282.  
  283.             When type = "***ARCLIVE" Then Do
  284.                 arcwipe = ""
  285.                 Say "Option enabled  : Noncrypted archive will NOT be deleted."
  286.             End
  287.  
  288.             When type = "***ASCCHAR" Then Do
  289.                 If data ~= "" Then Do
  290.                     ascchar = Left(Strip(data, 'B', '"'), 1)
  291.                     If ascchar = ";" | ascchar = "/" | ascchar = ":" | ascchar = "*" | ascchar = " " | ascchar = '"' | ascchar = binchar Then Do
  292.                         Say '***ERROR: "'||ascchar||'"is not allowed as forcing ASCII character.'
  293.                         Call Quit
  294.                     End
  295.  
  296.                     If ascchar ~= "" Then Say 'Force ASCII char: '||ascchar
  297.                 End
  298.                 Else Say 'Force ASCII char : None'
  299.             End
  300.  
  301.             When type = "***AUTOCHK" Then Do
  302.                 autochk = 0
  303.                 Say "Option enabled  : The  sum-file   will  be  added   commands,  making it an"
  304.                 Say "                  AmigaDos  script  which  will automatically check whether"
  305.                 Say "                  the  files  have  been  tampered, including itself.  Note"
  306.                 Say "                  that this is a MAJOR  security  hole,  read docs for more"
  307.                 Say "                  info."
  308.  
  309.                 If Open('chkconf', "ENV:SignArchOpts", 'R') Then Do
  310.                     If Upper(ReadLn('chkconf')) = "DO_NOT_ASK_FOR_CONFIRMATION_OF_AUTOCHK" Then Do
  311.                         autochk = 1
  312.                     End
  313.                 End
  314.  
  315.                 If autochk = 0 Then Do
  316.                     AddLib("rexxreqtools.library", 0, -30, 0)
  317.                     If Show("Libraries","rexxreqtools.library") Then Do
  318.                         rtresult = rtezrequest("Do you really wish to add a self-checking script? This" || '0A'X || "is a MAJOR security hole - read the docs!","_Yes|_No", "SignArch Warning", "rtez_defaultresponse=0")
  319.                         If rtresult = 1 Then autochk = 1
  320.                     End
  321.                     Else Do
  322.                         Say ""
  323.                         Say "Do you really wish to add a self-checking script? This"
  324.                          Options Prompt "is a MAJOR security hole - read the docs! (y/N)"
  325.                         Pull result
  326.                         If Upper(Strip(result)) = "Y" Then autochk = 1
  327.                     End
  328.                 End
  329.  
  330.                 If autochk = 0 Then Say "***NOTE: Self-checking script will NOT be added."
  331.  
  332.             End
  333.  
  334.             When type = "***BANNERS" Then Do
  335.                 If data ~= "" Then banner.bannum = '"'||Right(lineread, Length(lineread)-11)||'"'
  336.                 If bannum = 0 Then Say "Banner:"
  337.                 Address Command "Echo "||banner.bannum
  338.                 bannum = bannum + 1
  339.             End
  340.  
  341.             When type = "***BINCHAR" Then Do
  342.                 If data ~= "" Then Do
  343.                     binchar = Left(Strip(data, 'B', '"'), 1)
  344.                     If binchar = ";" | binchar = "/" | binchar = ":" | binchar = "*" | binchar = " " | binchar = '"' | binchar = ascchar Then Do
  345.                         Say '***ERROR: "'||binchar||'"is not allowed as forcing binary character.'
  346.                         Call Quit
  347.                     End
  348.  
  349.                     If binchar ~= "" Then Say 'Force bin. char : '||binchar
  350.                 End
  351.                 Else Say 'Force bin. char : None'
  352.             End
  353.  
  354.             When type = "***DEEPCHK" Then Do
  355.                 deepchk = "WHOLEFILE"
  356.                 Say "Option enabled  : Entire file scanned when checking whether a file is ASCII."
  357.             End
  358.  
  359.             When type = "***ENCRYPT" Then Do
  360.                 If cryptfile = 0 Then Do
  361.                     Say "Option enabled  : Final archive will be encrypted."
  362.                     If Open('cryptnames', "T:"||UniqueID||"SACryptFile", 'W') = 0 Then Do
  363.                         Say "***ERROR: Unable to open workfile!"
  364.                         Call Quit
  365.                     End
  366.                 End
  367.                 cryptfile = 1
  368.                 If data = "" Then Do
  369.                     Say "***ERROR: No name to encrypt to!"
  370.                     Call Quit
  371.                 End
  372.                 WriteLn('cryptnames', data)
  373.                 Say "Encrypt to      : "||data
  374.             End
  375.  
  376.             When type = "***ENDWAIT" Then Do
  377.                 endwait = 1
  378.                 Say "Option enabled  : Wait command only issued at end of checking-script."
  379.             End
  380.  
  381.             When type = "***EXECCMD" Then Do
  382.                 If data ~= "" Then Do
  383.                     Options Failat 500
  384.                     data = Strip(Right(lineread, Length(lineread)-11))
  385.                     Say "Executing cmd.  : "||data
  386.                     Address Command data
  387.                     If RC ~= 0 Then Do
  388.                         AddLib("rexxreqtools.library", 0, -30, 0)
  389.                         If Show("Libraries","rexxreqtools.library") Then Do
  390.                             rtresult = rtezrequest(data||"' failed returncode "||RC||'0A'X||"Continue?","_Yes|_No", "SignArch Warning", "rtez_defaultresponse=0")
  391.                             If rtresult = 0 Then Call Quit
  392.                         End
  393.                         Else Do
  394.                             Say ""
  395.                             Say "***'"||data||"' failed returncode "||RC
  396.                             Options Prompt "***Continue (Y/n)? "
  397.                             Pull result
  398.                             If Upper(Strip(result)) = "N" Then Call Quit
  399.                         End
  400.                     End
  401.                     Options Failat 21
  402.                 End
  403.                 Else Do
  404.                     Say "***ERROR: No parameter given to EXECCMD option!"
  405.                     Call Quit
  406.                 End
  407.             End
  408.  
  409.             When type = "***INCTEXT" Then Do
  410.                 If data ~= "" Then Do
  411.                     inctext = Strip(data, 'B', '"')
  412.                     Say "Include textfile: "||data
  413.                 End
  414.                 Else Do
  415.                     Say "***ERROR: No name specified for text to be included!"
  416.                     Call Quit
  417.                 End
  418.             End
  419.  
  420.             When type = "***LASTOPT" Then Do
  421.                 fileforced = 1
  422.                 Say "***Forcing option parsing complete..."
  423.                 Say ""
  424.             End
  425.  
  426.             When type = "***NOKEYADD" Then Do
  427.                 dontaddkey = 1
  428.                 Say "Option enabled  : Your PGP key will NOT be added to the sumfile"
  429.             End
  430.  
  431.             When type = "***NOWILDS" Then Do
  432.                 wildcards = 0
  433.             End
  434.  
  435.             When type = "***ROOTDIR" Then Do
  436.                 rootdir = Strip(data, 'B', '"')
  437.                 Say 'Rootdir set to  : "'||rootdir||'"'
  438.                 If Pragma("Directory", rootdir) = 0 Then Do
  439.                     Say "***ERROR: Unable to set rootdir!"
  440.                     Call Quit
  441.                 End
  442.             End
  443.  
  444.             When type = "***SIGNAME" Then Do
  445.                 If data ~= "" Then Do
  446.                     ID = data
  447.                     Say "Your ID/name    : "||ID
  448.                 End
  449.                 Else Say "No parameter given for SIGNAME option!"
  450.             End
  451.  
  452.             When type = "***SUMFILE" Then Do
  453.                 SUMFILE = data
  454.                 Say "Msg. digest file: "||SUMFILE
  455.                 Address Command 'Delete >nil: '||SUMFILE
  456.             End
  457.  
  458.             When type = "***SUMICON" Then Do
  459.                 sumicon = 1
  460.                 Say "Option enabled  : Icons will be summed."
  461.             End
  462.  
  463.             When type = "***SUMONLY" Then Do
  464.                 sumonly = 1
  465.                 Say "Option enabled  : No archiving will be done, only the sumfile will be created."
  466.             End
  467.  
  468.             When type = "***WAITCOM" Then Do
  469.                 If data ~= "" Then Do
  470.                     waittype = Strip(Right(lineread, Length(lineread)-11))
  471.                     Say "Wait command    : "||waittype
  472.                 End
  473.                 Else Do
  474.                     waittype = ""
  475.                     Say "Option enabled  : No waiting between commands"
  476.                 End
  477.             End
  478.  
  479.             When type = "***WAITRET" Then Do
  480.                 _waitforreturn = 1
  481.             End
  482.  
  483.              Otherwise Do
  484.                 Say "***ERROR: Unknown option!"
  485.                 Call Quit
  486.             End
  487.         End
  488.     End
  489.     lineread = ReadLn('flfile')
  490. End
  491.  
  492. Say "Option parsing complete..."
  493.  
  494. Call Close('cryptnames')
  495.  
  496.  
  497. If rootdir = "" Then Do
  498.     rootdir = curdir
  499.     Say 'Rootdir is still: '||rootdir
  500. End
  501.  
  502. /*
  503. *
  504. * Find the user's ID, via various methods
  505. *
  506. */
  507.  
  508.  
  509. If id = "" Then Do
  510.     ret = Open('pgppath', "ENV:PGPPATH", 'R')
  511.  
  512.     If ret ~= 0 Then Do
  513.         pgppath = Strip(ReadLn('pgppath'))
  514.         Close('pgppath')
  515.         If Right(pgppath, 1) ~= ":" & Right(pgppath, 1) ~= "/" Then pgppath = pgppath||"/"
  516.  
  517.         /* First, look in the pgp.config file */
  518.  
  519.         ret = Open('pgpconfig', pgppath||"config.txt", 'R')
  520.         If ret = 0 Then ret = Open('pgpconfig', pgppath||"pgp.config", 'R')
  521.  
  522.  
  523.         If Ret ~= 0 Then Do
  524.             Do While Eof('pgpconfig') = 0
  525.                 pgpline = Strip(ReadLn('pgpconfig'))
  526.                 If pgpline ~= "" & Left(pgpline, 1) ~= "#" Then Do
  527.                     If Abbrev(Upper(pgpline), "MYNAME") = 1 Then Do
  528.                         Do While Left(pgpline, 1) ~= "="
  529.                             pgpline = Right(pgpline, Length(pgpline)-1)
  530.                         End
  531.  
  532.                         pgpline = Right(pgpline, Length(pgpline)-1)
  533.                         pgpline = Strip(pgpline)
  534.  
  535.                         If Index(pgpline, '#') ~= 0 Then Do
  536.                             Do While Right(pgpline, 1) ~= "#"
  537.                                 pgpline = Left(pgpline, Length(pgpline)-1)
  538.                             End
  539.                             pgpline = Left(pgpline, Length(pgpline)-1)
  540.                         End
  541.  
  542.                         pgpline = Strip(pgpline)
  543.                         pgpline = Strip(pgpline, 'B', '"')
  544.  
  545.                         ID = '"'||pgpline||'"'
  546.                         Address Command pgpcommand||" >nil: -kv "||ID||" "||pgppath||"secring.pgp"
  547.                         If rc = 0 Then Do
  548.                             Say "Your ID/name    : "||ID
  549.                         End
  550.                         Else Do
  551.                             Say "***WARNING: Fault in pgp.config/config.txt. MyName param not found in secring.pgp."
  552.                             Id = ""
  553.                         End
  554.                     End
  555.                 End
  556.             End
  557.             Close('pgpconfig')
  558.         End
  559.         Else Say "Unable to open pgp.config/config.txt file!"
  560.  
  561.         /* If the pgpconfig file isn't useful, just use the first key on the */
  562.         /* secret keyring */
  563.  
  564.         If ID = "" Then Do
  565.             Address Command pgpcommand||' >T:'||UniqueID||'SATmpFile -kv '||pgppath||'secring.pgp'
  566.             If rc = 0 Then Do
  567.                 gotfirstid = 0
  568.                 If Open('satmpfile', "T:"||UniqueID||"SATmpFile", 'R') Then Do
  569.                     Do Until Eof('satmpfile') = 1
  570.                         pgpline = ReadLn('satmpfile')
  571.                         If Upper(Left(pgpline, 3)) = "SEC" Then Do
  572.                             gotfirstid = 1
  573.                             Leave
  574.                         End
  575.                     End
  576.                     Close('satmpfile')
  577.                 End
  578.                 If gotfirstid = 1 Then Do
  579.                     Parse Var pgpline keytype keybits keydate ID
  580.                     Drop keytype keybits keydate
  581.                     ID = Strip(ID)
  582.                     ID = Strip(ID, 'B', '"')
  583.                     ID = '"'||ID||'"'
  584.                     Address Command pgpcommand||" >nil: -kv "||ID||" "||pgppath||"secring.pgp"
  585.                     If rc = 0 Then Do
  586.                         Say "Your ID/name    : "||ID
  587.                         Close('pgpconfig')
  588.                     End
  589.                     Else Do
  590.                         Say "***ERROR: Unable to find your name!"
  591.                         Call Quit
  592.                     End
  593.                 End
  594.             End
  595.         End
  596.     End
  597.     Else Say "Unable to get env variable PGPPATH!"
  598. End
  599.  
  600. FoundID:
  601.  
  602. Say ""
  603.  
  604. If Strip(Strip(id, 'B', '"')) = "" Then Do
  605.     Say "***ERROR: Unable to get user ID!"
  606.     Call Quit
  607. End
  608.  
  609. If Strip(Strip(sumfile, 'B', '"')) = "" Then Do
  610.     Say "***ERROR: Unable to find name of sumfile!"
  611.     Call Quit
  612. End
  613.  
  614. If Strip(Strip(archive, 'B', '"')) = "" & sumonly = 0 Then Do
  615.     Say "***ERROR: Unable to find name of archive!"
  616.     Call Quit
  617. End
  618.  
  619. /* Make sure the sumfile exists */
  620.  
  621. Address Command 'Echo "Dummy" TO 'SUMFILE
  622.  
  623. /* Get full path for it */
  624.  
  625. Address Command 'List >T:'||UniqueID||'SAWTmpFile '||SUMFILE||' LFORMAT %f%s'
  626. If Open('sawtmpfile', "T:"||UniqueID||"SAWTmpFile", 'R') Then Do
  627.     sumfile = ReadLn('sawtmpfile')
  628.     Close('sawtmpfile')
  629. End
  630. Else Do
  631.     Say "***ERROR: Unable to get full sumfile name!"
  632.     Call Quit
  633. End
  634.  
  635. If sumfile = "" Then Do
  636.     Say "***ERROR: Unable to examine sumfile! Empty dir?"
  637.     Call Quit
  638. End
  639.  
  640. Address Command 'Delete >nil: "'||SUMFILE||'"'
  641.  
  642. /* Get the full path for the rootdir */
  643.  
  644. Address Command 'List >T:'||UniqueID||'SAWTmpFile LFORMAT %f'
  645. If Open('sawtmpfile', "T:"||UniqueID||"SAWTmpFile", 'R') Then Do
  646.     fullrootdir = ReadLn('sawtmpfile')
  647.     Close('sawtmpfile')
  648. End
  649. Else Do
  650.     Say "***ERROR: Unable to get full root path name!"
  651.     Call Quit
  652. End
  653.  
  654. If fullrootdir = "" Then Do
  655.     Say "***ERROR: Unable to examine rootdir! Empty dir?"
  656.     Call Quit
  657. End
  658.  
  659. /* Check that the sumfile is within (a subdir of) the rootdir */
  660.  
  661. If Left(sumfile, Length(fullrootdir)) = fullrootdir Then Do
  662.     sumfile = Right(sumfile, Length(sumfile)-Length(fullrootdir))
  663. End
  664. Else Do
  665.     Say "***ERROR: You can't put the sumfile above the ROOTDIR!"
  666.     Call Quit
  667. End
  668.  
  669. /* Get the directory of the sumfile, relative to the rootdir */
  670.  
  671. sumdir = sumfile
  672. sumdir = Strip(sumdir)
  673. sumdir = Strip(sumdir, 'B', '"')
  674.  
  675. If (Index(sumfile, "/") = 0 & Index(sumfile, ":") = 0) Then sumdir = ""
  676. Else Do While Right(sumdir, 1) ~= "/" & Right(sumdir, 1) ~= ":" & Length(sumdir) > 0
  677.     sumdir = Left(sumdir, Length(sumdir)-1)
  678. End
  679.  
  680. sumdirlevels = Length(sumdir)-Length(Compress(sumdir,"/"))
  681. sumfilefile = Strip(sumfile, 'B', '"')
  682. sumfilefile = Strip(Right(sumfilefile, Length(sumfilefile)-Length(sumdir)), 'B', '"')
  683.  
  684. If sumfilefile = "" Then Do
  685.     Say "***ERROR: No filename for sumfile!?!?!"
  686.     Call Quit
  687. End
  688.  
  689. If Open('satmpfile', "T:"||UniqueID||"SaTmpFile", 'W') = 0 Then Do
  690.     Say "***ERROR: Unable to open temporary file!"
  691.     Call Quit
  692. End
  693.  
  694. /* "Avoid" a bug in PGP */
  695.  
  696. WriteLn('satmpfile', "; /*** CLEARSIGNED MESSAGE BEGINS HERE, ALL DATA ABOVE MUST BE IGNORED ***/")
  697.  
  698. If commnum > 0 Then Do
  699.     Do count = 0 To commnum-1
  700.         WriteLn('satmpfile',command.count)
  701.     End
  702.     If autochk = 0 Then Writeln('satmpfile', "Quit")
  703. End
  704.  
  705. /* Create necessary files and lines for self-checking script */
  706.  
  707. If autochk = 1 Then Do
  708.     If Open('beginfile', sumdir||"-----BEGIN", 'W') Then Do
  709.         Sftlen = (Length(Sumfilefile)+8)%4
  710.         If SftLen > 255 Then Do
  711.             Say "***ERROR: Length of sumfile name too long! Aborting!"
  712.             Call Quit
  713.         End
  714.  
  715.         SftLen = D2C(SftLen)
  716.  
  717.         Say "Creating dummy file to avoid self-check script failure..."
  718.  
  719. /* For a disassembly of this, look in the Source directory */
  720.  
  721.         WriteCh('beginfile', '000003F3 00000000 00000002 00000000 00000001'X)
  722.         WriteCh('beginfile', '0000004B 000000'X)
  723.  
  724.         WriteCh('beginfile', SftLen)
  725.  
  726.         WriteCh('beginfile', '000003E9 0000004B 7E142C78 000443FA 00CC4EAE'X)
  727.         WriteCh('beginfile', 'FE684A80 67000084 2C407E0A 223AFFE2 D281D281'X)
  728.         WriteCh('beginfile', '58812C01 243C0000 03ED4EAE FFE22800 67284FEF'X)
  729.         WriteCh('beginfile', 'FFD82200 240F7624 4EAEFFD6 B6806620 204F43FA'X)
  730.         WriteCh('beginfile', '00687423 1018B019 661C51CA FFF87E00 602841FA'X)
  731.         WriteCh('beginfile', '0084487A 002C6012 41FA008F 487A001C 600841FA'X)
  732.         WriteCh('beginfile', '009F487A 000E6122 2046611E 41FA00AB 60184FEF'X)
  733.         WriteCh('beginfile', '00282204 4EAEFFDC 224E2C78 00044EAE FE622007'X)
  734.         WriteCh('beginfile', '4E752408 76FF4A18 57CBFFFC 46834EAE FFC42200'X)
  735.         WriteCh('beginfile', '4EEEFFD0 2D2D2D2D 2D424547 494E2050 47502053'X)
  736.         WriteCh('beginfile', '49474E45 44204D45 53534147 452D2D2D 2D2D0A0A'X)
  737.         WriteCh('beginfile', '646F732E 6C696272 61727900 43616E27 74206F70'X)
  738.         WriteCh('beginfile', '656E2073 756D6669 6C652022 0043616E 27742072'X)
  739.         WriteCh('beginfile', '65616420 66726F6D 2073756D 66696C65 20220043'X)
  740.         WriteCh('beginfile', '4845434B 20464149 4C454420 494E2053 554D4649'X)
  741.         WriteCh('beginfile', '4C452022 00220A00 000003F2 000003EA 000000'X)
  742.  
  743.         WriteCh('beginfile', SftLen)
  744.  
  745.         WriteCh('beginfile', Sumfilefile)
  746.  
  747.         Sftlen = ((Length(Sumfilefile)+8)%4)*4
  748.  
  749.         Count = Length(Sumfilefile)
  750.  
  751.         Do While Count < SftLen
  752.             WriteCh('beginfile', '00'X)
  753.             Count = Count + 1
  754.         End
  755.  
  756.         WriteCh('beginfile', '000003F2'X)
  757.  
  758.         Close('beginfile')
  759.     End
  760.     Else Do
  761.         Say "***ERROR: Unable to create '-----BEGIN' file. Auto-checking script won't work."
  762.         Call Quit
  763.     End
  764.  
  765.     If bannum > 0 Then Do count = 0 To bannum-1
  766.         WriteLn('satmpfile',"Echo "||banner.count)
  767.     End
  768.  
  769.     WriteLn('satmpfile','PGP -ka "'||SUMFILEFILE||'"')
  770.     If waittype ~= "" & endwait = 0 Then WriteLn('satmpfile', waittype)
  771.     WriteLn('satmpfile','PGP -o T:PGPTest.asc "'||SUMFILEFILE||'"')
  772.     If waittype ~= "" & endwait = 0 Then WriteLn('satmpfile', waittype)
  773.     WriteLn('satmpfile','MD5SUM -cv T:PGPTest.asc')
  774.     WriteLn('satmpfile',"Delete >nil: T:PGPTest.asc")
  775.     If waittype ~= "" Then WriteLn('satmpfile', waittype)
  776.     WriteLn('satmpfile',"Quit")
  777. End
  778. Else Do
  779.     If bannum > 0 Then Do count = 0 To bannum-1
  780.         WriteLn('satmpfile',banner.count)
  781.     End
  782. End
  783.  
  784. /* Include the "readme" file, if wanted */
  785.  
  786. If inctext ~= "" Then Do
  787.     Address Command 'ChkASCII "'||inctext||'" WHOLEFILE'
  788.     If rc ~= 0 Then Do
  789.         If rc = 5 Then Say "***WARNING: Text to be included is not ASCII!"
  790.         If rc = 20 Then Do
  791.             Say "***ERROR: Could not check whether INCTEXT file is ASCII or binary!"
  792.             Call Quit
  793.         End
  794.     End
  795.     If Open('incfile', inctext, 'R') = 1 Then Do
  796.         Say "Including file "||inctext||"..."
  797.         WriteLn('satmpfile', "")
  798.         WriteLn('satmpfile', "===                      Included text file begins                      ===")
  799.         WriteLn('satmpfile', "")
  800.         WriteLn('satmpfile', "")
  801.         Do Until Eof('incfile') = 1
  802.             incline = ReadLn('incfile')
  803.             If WriteLn('satmpfile', incline) <= 0 Then Do
  804.                 Say "***ERROR: Unable to include file!"
  805.                 Call Quit
  806.             End
  807.         End
  808.         WriteLn('satmpfile', "")
  809.         WriteLn('satmpfile', "")
  810.         WriteLn('satmpfile', "===                       Included text file ends                       ===")
  811.         WriteLn('satmpfile', "")
  812.         Close('incfile')
  813.     End
  814. End
  815.  
  816. /* Write some informative lines... */
  817.  
  818. WriteLn('satmpfile',"")
  819. WriteLn('satmpfile',"=== File created using SignArch v1.1, © 1994 Jens T. Berger Thielemann. ===")
  820. WriteLn('satmpfile',"")
  821.  
  822. WriteLn('satmpfile',"=== To check the contents of this file, change the current directory to ===")
  823. WriteLn('satmpfile',"=== to that of this file, and enter the following commands:             ===")
  824. WriteLn('satmpfile',"")
  825. WriteLn('satmpfile','PGP -ka "'||SUMFILEFILE||'"')
  826. WriteLn('satmpfile','PGP -o T:PGPTest.asc "'||SUMFILEFILE||'"')
  827. WriteLn('satmpfile','MD5SUM -cv T:PGPTest.asc')
  828. WriteLn('satmpfile',"")
  829. If autochk = 1 Then Do
  830.     WriteLn('satmpfile',"===        You may also just execute this file as a Shell script.       ===")
  831.     WriteLn('satmpfile',"")
  832. End
  833.  
  834. WriteLn('satmpfile',"===                      Signatures begin below                         ===")
  835. Close('satmpfile')
  836.  
  837. icon = 0
  838.  
  839. forcechar = ""
  840.  
  841. /* Trace ?ACEILRS */
  842.  
  843. /* Get the names of the files to archive */
  844.  
  845. If wildcards = 1 Then Do
  846.     Say "Parsing wildcards..."
  847.     If Open('sawildfile', "T:"||UniqueID||"SAWildFile", 'W') Then Do
  848.         Do Until Eof('flfile') = 1
  849.             If Strip(lineread) ~= "" & Left(Strip(lineread), 1) ~= ";" Then Do
  850.                 lineread = Strip(Strip(lineread), 'B', '"')
  851.  
  852.                   /* Take care of ASCCHAR/BINCHAR */
  853.  
  854.                 manylines = ""
  855.  
  856.                 Select
  857.                     When Left(lineread, 1) = ascchar | Left(lineread, 1) = binchar Then Do
  858.                         forcechar = Left(lineread, 1)
  859.                         manylines = '"'||Right(lineread, Length(lineread)-1)||'"'
  860.                         Do Until Eof('flfile') = 1 | ( Strip(lineread) ~= "" & Left(Strip(lineread), 1) ~= ";" )
  861.                             lineread = Strip(ReadLn('flfile'))
  862.                             lineread = Strip(Strip(lineread), 'B', '"')
  863.                         End
  864.                     End
  865.                     When Length(lineread) > 50 Then Do
  866.                         If lineread ~= "" & Left(Strip(lineread), 1) ~= ";" Then manylines = '"'||lineread'"'
  867.                         Do Until Eof('flfile') = 1 | ( Strip(lineread) ~= "" & Left(Strip(lineread), 1) ~= ";" )
  868.                             lineread = Strip(ReadLn('flfile'))
  869.                             lineread = Strip(Strip(lineread), 'B', '"')
  870.                         End
  871.                     End
  872.                     Otherwise Do
  873.                         forcechar = ""
  874.                         Do While Left(lineread, 1) ~= ascchar & Left(lineread, 1) ~= binchar & Eof('flfile') = 0 & Length(manylines) < 400 & Length(lineread) < 50
  875.                             If Strip(lineread) ~= "" & Left(Strip(lineread), 1) ~= ";" Then Do
  876.                                 manylines = manylines||' "'||lineread||'"'
  877.                             End
  878.                             Do Until Eof('flfile') = 1 | ( Strip(lineread) ~= "" & Left(Strip(lineread), 1) ~= ";" )
  879.                                 lineread = Strip(ReadLn('flfile'))
  880.                                 lineread = Strip(Strip(lineread), 'B', '"')
  881.                             End
  882.                         End
  883.                     End
  884.                 End
  885.  
  886.                 Address Command 'List >T:'||UniqueID||'SAWTmpfile '||manylines||' LFORMAT %f%s ALL FILES'
  887.                 If rc = 0 Then Do
  888.                     If Open('sawtmpfile', "T:"||UniqueID||"SAWTmpFile", 'R') = 1 Then Do
  889.                         Do Until Eof('sawtmpfile') = 1
  890.                             wildfile = ReadLn('sawtmpfile')
  891.                             If wildfile ~= "" Then Do
  892.                                 If Left(wildfile, Length(fullrootdir)) = fullrootdir Then Do
  893.                                     WriteLn('sawildfile', forcechar||Right(wildfile, Length(wildfile)-Length(fullrootdir)))
  894.                                     Say "    "||Right(wildfile, Length(wildfile)-Length(fullrootdir))
  895.                                 End
  896.                                 Else Do
  897.                                     Say "***ERROR: Files exist above rootdir!"
  898.                                     Call Quit
  899.                                 End
  900.                             End
  901.                         End
  902.                         Close('sawtmpfile')
  903.                     End
  904.                     Else Do
  905.                         Say "***ERROR: Unable to open temporary file!"
  906.                         Call Quit
  907.                     End
  908.                 End
  909.                 Else Do
  910.                     Say "***ERROR: Unable to get information for file "||lineread
  911.                     Call Quit
  912.                 End
  913.             End
  914.             Else Do
  915.                 lineread = Strip(ReadLn('flfile'))
  916.             End
  917.         End
  918.     End
  919.     Else Do
  920.         Say "***ERROR: Unable to open temporary file!"
  921.         Call Quit
  922.     End
  923. End
  924. Else Do
  925.     /* Trace ?ACEILRS */
  926.     Say "Copying filenames..."
  927.     If Open('sawildfile', "T:"||UniqueID||"SAWildFile", 'W') Then Do
  928.         Do Until Eof('flfile') = 1
  929.             If lineread ~= "" & Left(lineread, 1) ~= ";"Then Do
  930.                 If Left(lineread, Length(fullrootdir)) = fullrootdir Then Do
  931.                     WriteLn('sawildfile', forcechar||Right(lineread, Length(lineread)-Length(fullrootdir)))
  932.                 End
  933.                 Else Do
  934.                     Say "***ERROR: Files exist above rootdir!"
  935.                     Call Quit
  936.                 End
  937.             End
  938.             lineread = ReadLn('flfile')
  939.         End
  940.     End
  941.     Else Do
  942.         Say "***ERROR: Unable to open temporary file!"
  943.         Call Quit
  944.     End
  945. End
  946.  
  947. If autochk = 1 Then Do
  948.     Say
  949.     Say "Adding dummy file to make sure the script works properly."
  950.     WriteLn('sawildfile', SUMDIR||"-----BEGIN")
  951. End
  952.  
  953.  
  954. Close('flfile')
  955. Close('sawildfile')
  956.  
  957. /* Trace ?ACEILRS */
  958.  
  959. If sumfileicon = 1 Then Do
  960.     If Exists(Sumfile||".info") = 0 Then Do
  961.         Say "Creating icon for sumfile..."
  962.         If autochk = 1 | commnum > 0 Then Do
  963.             Address Command 'Copy FROM ENV:sum_scr.info TO "'||Sumfile||'.info"'
  964.         End
  965.         Else Do
  966.             Address Command 'Copy FROM ENV:sum_dta.info TO "'||Sumfile||'.info"'
  967.         End
  968.     End
  969.     Address Command 'Search >nil: "T:'||UniqueID||'SAWildFile" "'||Sumfile||'.info" QUIET'
  970.     If rc ~= 0 Then Do
  971.         If Open('sawildfile', "T:"||UniqueID||"SAWildFile", 'A') Then Do
  972.             Seek('sawildfile', 0, 'E')
  973.             WriteLn('sawildfile', Sumfile||'.info')
  974.             Close('sawildfile')
  975.         End
  976.         Else Do
  977.             Say "***ERROR: Can't open temporary file!"
  978.             Call Quit
  979.         End
  980.     End
  981. End
  982.  
  983.  
  984.  
  985. If Open('flfile', "T:"||UniqueID||"SAWildFile", 'R') = 0 Then Do
  986.     Say "***ERROR: Unable to open work file!"
  987.     Call Quit
  988. End
  989.  
  990. If Pragma("Directory", sumdir) = 0 Then Do
  991.     Say "***ERROR: Unable to locate drawer of sum-file!"
  992.     Call Quit
  993. End
  994.  
  995. FoundSumFile = 0
  996.  
  997. Say ""
  998.  
  999. If Open('salistfile', "T:"||UniqueID||"SAListFile", 'W') = 1 Then Do
  1000.     Do While Eof('flfile') = 0
  1001.         fileline = ReadLn('flfile')
  1002.         If fileline ~= "" & Left(fileline, 1) ~= ";" Then Do
  1003.  
  1004.             fileline = Strip(fileline)
  1005.             fileline = Strip(fileline, 'B', '"')
  1006.  
  1007.             /* Take care of BINCHAR/ASCCHAR information */
  1008.  
  1009.             Select
  1010.                 When Left(fileline, 1) = binchar & binchar ~= "" Then Do
  1011.                     fileline = Right(fileline, Length(fileline)-1)
  1012.                     fileline = Strip(fileline, 'B', '"')
  1013.                     Say "*** Forcing "||fileline||" to binary."
  1014.                     cares = 5
  1015.                     forced = 1
  1016.                     tmpicon = 0
  1017.                 End
  1018.                 When Left(fileline, 1) = ascchar & ascchar ~= "" Then Do
  1019.                     fileline = Right(fileline, Length(fileline)-1)
  1020.                     fileline = Strip(fileline, 'B', '"')
  1021.                     Say "*** Forcing "||fileline||" to ASCII."
  1022.                     cares = 0
  1023.                     forced = 1
  1024.                     tmpicon = 0
  1025.                 End
  1026.                 Otherwise Do
  1027.                     forced = 0
  1028.                     tmpicon = 1
  1029.                 End
  1030.             End
  1031.  
  1032.             /* Write the filename without ASCCHAR/BINCHAR information */
  1033.  
  1034.             /* If the file begins with '-' one must add a '-' to the name */
  1035.  
  1036.             If Left(fileline, 1) = '-' Then WriteLn('salistfile', "-"||fileline)
  1037.             Else WriteLn('salistfile', fileline)
  1038.  
  1039.             If Index(Upper(fileline), Upper(sumdir)) = 1 Then fileline = Right(fileline, Length(fileline)-Length(sumdir))
  1040.             Else fileline = Copies("/", sumdirlevels)||fileline
  1041.  
  1042.             If sumicon = 0 | tmpicon = 1 Then Do
  1043.                 icon = 0
  1044.                 If Upper(Right(fileline, 5)) = ".INFO" Then Do
  1045.                     If Open('icon', fileline, 'R') ~= 0 Then Do
  1046.                         magic = ReadCh('icon', 2)
  1047.                         Close('icon')
  1048.                         If magic = 'E310'X Then Do
  1049.                             icon = 1
  1050.                         End
  1051.                     End
  1052.                 End
  1053.             End
  1054.  
  1055.  
  1056.             /* Trace ?ACEILRS */
  1057.  
  1058.             fileline = '"'||Strip(fileline, 'B', '"')||'"'
  1059.             If Index(fileline, ":") ~= 0 Then Do
  1060.                 Say "***WARNING: Root directory information is present in filename.  End-user"
  1061.                 Say "***         may  experience  trouble  checking the message digests.  You"
  1062.                 Say "***         are strongly urged to remove this information from your file"
  1063.                 Say "***         to avoid problems."
  1064.             End
  1065.  
  1066.             If (icon = 0 | tmpicon = 0) & (Upper(Strip(fileline, 'B', '"')) ~= Upper(SUMFILEFILE)) Then Do
  1067.                 If forced = 0 Then Do
  1068.                     Address Command 'ChkASCII FILENAME '||fileline||' '||deepchk
  1069.                     cares = rc
  1070.                 End
  1071.  
  1072.                 If cares = 20 Then Do
  1073.                     Say "***ERROR: ChkASCII could not check file "||fileline||"! File not found?"
  1074.                     Close('salistfile')
  1075.                     Call Quit
  1076.                 End
  1077.                 If Left(fileline, 2) = '"-' Then Do
  1078.                     Say "***NOTE: Please ignore the next `Invalid argument' message."
  1079.                     filetosum = '"" '||fileline
  1080.                     hack = 1
  1081.                 End
  1082.                 Else Do
  1083.                     filetosum = fileline
  1084.                     hack = 0
  1085.                 End
  1086.  
  1087.                 If cares = 5 Then Do
  1088.                     Say "Summing binary file "||fileline||"..."
  1089.                     Address Command md5command||' >>T:'||UniqueID||'SaTmpFile -b '||filetosum
  1090.                     If rc ~= 0 & (hack = 0 | Exists(Strip(fileline, 'B', '"')) = 0) Then Do
  1091.                         Say "***ERROR: Could not sum file "||fileline||"!"
  1092.                         Call Quit
  1093.                     End
  1094.                 End
  1095.                 Else Do
  1096.                     Say "Summing ASCII  file "||fileline||"..."
  1097.                     Address Command md5command||' >>T:'||UniqueID||'SaTmpFile '||filetosum
  1098.                     If rc ~= 0 & (hack = 0 | Exists(Strip(fileline, 'B', '"')) = 0) Then Do
  1099.                         Say "***ERROR: Could not sum file "||fileline||"!"
  1100.                         Call Quit
  1101.                     End
  1102.                 End
  1103.             End
  1104.             Else Do
  1105.                 If Upper(Strip(fileline, 'B', '"')) = Upper(SUMFILEFILE) Then Do
  1106.                     FoundSumFile = 1
  1107.                 End
  1108.             End
  1109.         End
  1110.     End
  1111. End
  1112.  
  1113. If FoundSumFile = 0 Then WriteLn('salistfile', SUMFILE)
  1114.  
  1115. Close('salistfile')
  1116.  
  1117. /* We've created the file with message digests, now let's sign it */
  1118.  
  1119. Address Command pgpcommand||" -fast +CLEARSIG=ON +ARMORLINES=0 <T:"||UniqueID||"SATmpFile >T:"||UniqueID||"SASigFile -u "||ID
  1120. cares = rc
  1121. Say ""
  1122.  
  1123. If Pragma("Directory", fullrootdir) = 0 Then Do
  1124.     Say "***ERROR: Unable to re-set dir to rootdir!"
  1125.     Call Quit
  1126. End
  1127.  
  1128. Success = FALSE
  1129.  
  1130. If cares = 0 Then Do
  1131.  
  1132.     /* Add the PGP key */
  1133.  
  1134.     If dontaddkey = 0 Then Do
  1135.         Address Command pgpcommand|| " -kxaf "||ID||" >T:"||UniqueID||"SAKeyFile"
  1136.         pgprc = rc
  1137.     End
  1138.     Else pgprc = 0
  1139.  
  1140.     If pgprc = 0 Then Do
  1141.  
  1142.         Say ""
  1143.  
  1144.         If dontaddkey = 0 Then Address Command "Join T:"||UniqueID||"SASigFile T:"||UniqueID||'SAKeyFile TO "'||SUMFILE||'"'
  1145.         Else Address Command 'Copy T:'||UniqueID||'SASigFile TO "'||SUMFILE||'"'
  1146.  
  1147.         If rc = 0 Then Do
  1148.             If autochk = 1 | commnum ~= 0 Then Address Command 'Protect "'||SUMFILE||'" S ADD'
  1149.  
  1150.             If sumonly = 0 Then Do
  1151.  
  1152.                 /* Make sure the archive has ".lha" as extension */
  1153.  
  1154.                 ARCHIVE = Strip(Archive, 'B', '"')
  1155.                 Archive = Strip(Archive)
  1156.  
  1157.                 /* Trace ? */
  1158.  
  1159.                 arcbody = Archive
  1160.                 Do While Right(arcbody, 1) ~= "." & Length(arcbody) ~= 0 & Right(arcbody, 1) ~= "/" & Right(arcbody, 1) ~= ":"
  1161.                     arcbody = Left(arcbody, Length(arcbody)-1)
  1162.                 End
  1163.  
  1164.                 If Length(arcbody) > 0 & Right(arcbody, 1) = "." Then arcbody = Left(arcbody, Length(arcbody)-1)
  1165.  
  1166.                 If ArcBody = "" | Right(arcbody, 1) = "/" | Right(arcbody, 1) = ":" Then arcbody = Archive
  1167.  
  1168.                 ArcExt = Right(Archive, Length(Archive) - Length(ArcBody))
  1169.  
  1170.                 If cryptfile = 1 | addarmor = "a" Then Do
  1171.                     If Upper(arcext) ~= ".LZH" Then arcext = ".LZH"
  1172.                 End
  1173.                 Else Do
  1174.                     If Upper(arcext) ~= ".LHA" Then arcext = ".LHA"
  1175.                 End
  1176.  
  1177.                 If Exists(arcbody||arcext) Then Address Command 'Delete "'||arcbody||arcext||'"'
  1178.  
  1179.                 Address Command lhacommand||' -xa -iT:'||UniqueID||'SaListFile a "'||arcbody||arcext||'"'
  1180.                 If rc = 0 Then Do
  1181.                     Say ""
  1182.                     Say "Archive & sum-file successfully created."
  1183.                     success = TRUE
  1184.                     If addarmor = "a" & cryptfile = 0 Then Do
  1185.                         success = FALSE
  1186.                         Address Command 'Delete <>nil: "'||ArcBody||'.as?"'
  1187.                         Say "ASCII-fying archive..."
  1188.  
  1189.                         Address Command pgpcommand||' -a -o "'||ArcBody||'" "'||ArcBody||ArcExt||'"'
  1190.  
  1191.                         If rc = 0 Then Do
  1192.                             Say "Archive successfully ASCII-fied."
  1193.                             Arcext = ".asc"
  1194.                             success = TRUE
  1195.                         End
  1196.                     End
  1197.                 End
  1198.                 Else Do
  1199.                     Say ""
  1200.                     Say "Something went wrong when creating archive."
  1201.                     If cryptfile = 1 Then Do
  1202.                         AddLib("rexxreqtools.library", 0, -30, 0)
  1203.                         If Show("Libraries","rexxreqtools.library") Then Do
  1204.                             rtresult = rtEZRequest("Creation of archive may have failed."||'0A'X||"Still try to encrypt?", "_Yes|_No", "SignArch ERROR", "rtez_defaultresponse=0")
  1205.                             If rtresult = 0 Then Do
  1206.                                 Say "Exiting WITHOUT encrypting..."
  1207.                                 Call Quit
  1208.                             End
  1209.                         End
  1210.                         Else Do
  1211.                             Say "Creation of archive may have failed."
  1212.                             Options Prompt "Still try to encrypt (y/N)? "
  1213.                             Pull result
  1214.                             If Upper(Strip(result)) ~= "Y" Then Do
  1215.                                 Say "Exiting WITHOUT encrypting..."
  1216.                                 Call Quit
  1217.                             End
  1218.                         End
  1219.                     End
  1220.                 End
  1221.  
  1222.                 If cryptfile = 1 Then Do
  1223.                     success = FALSE
  1224.                     If Addarmor = "a" Then ArcExt = ".asc"
  1225.                     Else ArcExt = ".pgp"
  1226.  
  1227.                     If Exists(ArcBody||ArcExt) Then Address Command 'Delete "'||ArcBody||ArcExt||'"'
  1228.  
  1229.                     Address Command pgpcommand||" -es"||ADDARMOR||ARCWIPE||" -u "||ID||' -o "'||ArcBody||ArcExt||'" "'||ArcBody||'.lzh" @T:'||UniqueID||'SACryptFile'
  1230.                     If rc = 0 Then Do
  1231.  
  1232.                         Say "Archive successfully encrypted."
  1233.                         success = TRUE
  1234.                     End
  1235.                     Else Say "***ERROR: Unable to encrypt file!"
  1236.                 End
  1237.             End
  1238.             Else Do
  1239.                 Say "Sumfile successfully created."
  1240.                 ArcBody = SumFile
  1241.                 ArcExt = ""
  1242.                 success = TRUE
  1243.             End
  1244.         End
  1245.         Else Say "***ERROR: Unable to create final sumfile!"
  1246.     End
  1247.     Else Say "***ERROR: Unable to extract your Public Key!"
  1248. End
  1249. Else Say "***ERROR: Unable to sign file with signatures!"
  1250.  
  1251. If success = TRUE Then Do
  1252.     elapsed = Time('E')
  1253.     mins = elapsed % 60
  1254.     secs = elapsed - (mins * 60)
  1255.     Say 'Final filename : '||ArcBody||ArcExt
  1256.     Say 'Operation succeeded in '||mins||' minute(s) and '||secs||' second(s).'
  1257.     _waitforreturn = 0
  1258. End
  1259.  
  1260.  
  1261. Call Quit
  1262.  
  1263. Break_c:
  1264. Break_d:
  1265.     Say "Break signal detected. Exiting..."
  1266. Quit:
  1267.     Call Close('flfile')
  1268.     Call Close('pgppath')
  1269.     Call Close('pgpconfig')
  1270.     Call Close('satmpfile')
  1271.     Call Close('sawtmpfile')
  1272.     Call Close('sawildfile')
  1273.     Call Close('salistfile')
  1274.     Call Close('cryptnames')
  1275.     Address Command "Delete >nil: T:"||UniqueID||"SaCryptFile T:"||UniqueID||"SaKeyFile T:"||UniqueID||"SaSigFile T:"||UniqueID||"SaTmpFile T:"||UniqueID||"SaListFile T:"||UniqueID||"SaWTmpFile T:"||UniqueID||"SaWildFile"
  1276.     If Open('curdir', "T:"||UniqueID||"SaCDFile", 'R') = 1 Then Do
  1277.         CurDir = Readln('curdir')
  1278.         Pragma("Directory", CurDir)
  1279.         Call Close('curdir')
  1280.         Address Command "Delete >nil: T:"||UniqueID||"SaCDFile"
  1281.     End
  1282.     Call Close('curdir')
  1283.     Call Close('saisrunning')
  1284.     Address Command 'Delete >nil: "T:SignArch is running!"'
  1285.     If _waitforreturn = 1 Then Do
  1286.         Options Prompt "Press <return> to continue..."
  1287.         Pull result
  1288.     End
  1289. If Success = TRUE Then Exit
  1290. Else Exit 10
  1291.  
  1292.